﻿using Furion.DependencyInjection;
using OrderSystemApi.Pojo;
using Snowflake.Core;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace OrderSystemApi.Services
{
    public class OrderService : ITransient
    {
        private readonly ISqlSugarRepository<Order> _iSqlSugarRepository;
        private readonly SqlSugarClient db;
        private readonly IdWorker worker = new IdWorker(1, 1);
        public OrderService(ISqlSugarRepository<Order> sqlSugarRepository)
        {
            _iSqlSugarRepository = sqlSugarRepository;
            db = _iSqlSugarRepository.Context;
        }      
        /**
         * 查询所有订单
         */
        public List<Order> getOrderList()
        {
            var orderList = db.Queryable<Order>()
                .Mapper(o =>
                {
                    o.OrderDetails = db.Queryable<OrderDetails>().Mapper(od => od.Goods, od => od.GoodsId)
                    .Where(od => od.OrderId == o.Id).ToList();
                })
                .Mapper(o => o.Buyer, o => o.BuyerId)
                .ToList();
            return orderList;
        }
        /**
         * 根据ID查询订单
         */
        public Order getOrderById(long id)
        {
            var order = db.Queryable<Order>()
                .Mapper((o) =>
                {
                    o.OrderDetails = db.Queryable<OrderDetails>()
                    .Mapper(od => od.Goods, od => od.GoodsId)
                    .Where(od => od.OrderId == o.Id).ToList();

                })
                .Mapper(o => o.Buyer, o => o.BuyerId)
                .First(o => o.Id == id);
            return order;
        }
        /**
         * 根据姓名查询订单
         */
        public List<Order> getOrderByName(string name)
        {
            var orderList = db.Queryable<Order>()
                .Mapper((o) =>
                {
                    o.OrderDetails = db.Queryable<OrderDetails>()
                    .Mapper(od => od.Goods, od => od.GoodsId)
                    .Where((od) => od.OrderId == o.Id).ToList();

                })
                .Mapper(o => o.Buyer, o => o.BuyerId)
                .Where(o => o.Buyer.Name == name).ToList();
            return orderList;
        }

        /**
         * 添加订单
         */
        public Order addOrder(Order order)
        {
            try
            {
                order.Buyer.Id = worker.NextId();
                order.BuyerId = order.Buyer.Id;
                db.Insertable(order.Buyer).ExecuteCommand();
                //计算总金额
                double sum = 0;
                foreach(OrderDetails orderDerails in order.OrderDetails)
                {
                    orderDerails.Id = worker.NextId();    
                    orderDerails.Goods.Id = worker.NextId();
                    orderDerails.GoodsId = orderDerails.Goods.Id;
                    db.Insertable(orderDerails.Goods).ExecuteCommand();
                    sum += orderDerails.GoodsNum * orderDerails.Goods.Price;
                }
                order.Sum = sum;
                db.Insertable(new Order()
                {
                    Id = order.Id,
                    BuyerId = order.BuyerId,
                    Sum = order.Sum,
                    OrderDetails = order.OrderDetails
                }).AddSubList(o => o.OrderDetails.First().OrderId).ExecuteCommand();
                return this.getOrderById(order.Id);
            }
            catch
            {
                return null;
            }
        }
        /**
         * 修改订单
         */
        public Order updateOrder(long id, Order order)
        {
            try
            {
                if (this.getOrderById(id) == null)
                {
                    return null;
                }
                this.deleteOrder(id);
                this.addOrder(order);
                return this.getOrderById(id);
            }
            catch
            {
                return null;
            }
        }
        /**
         * 删除订单
         */
        public int deleteOrder(long id)
        {
            try
            {
                return db.Deleteable<Order>().In(id).ExecuteCommand();
            }
            catch
            {
                return 0;
            }
        }
    }
}
